#include "SerialPortClient.h"

extern QString recvvalue;
extern intListener recfl;

struct order
{
    // 可以添加一个函数来序列化结构体
    QByteArray toByteArray(QString header,QString type,QString len,QString data,QString cd,QString tail) const {
        QString all = header+type+len+data+cd+tail;
        QByteArray byteArray;
        for(int i = 0;i<all.size();i++)
        {
            if(all[i]==' ')
                continue;   //跳过
            int num  = all.mid(i,2).toUInt(nullptr,16);
            i++;
            byteArray.append(num);
        }
        return byteArray;
    }
};

SerialportClient::SerialportClient(QObject *parent): QSerialPort(parent)
{
    mapGZ = new QMap<QString, QString>();
    mapGZ->insert("0B","EEROM初始化错误");
    mapGZ->insert("0C","温度采集初始化失败");
    mapGZ->insert("0D","温度读取失败");
    mapGZ->insert("0E","A区温度过高");
    mapGZ->insert("0F","B区温度过高");
    mapGZ->insert("10","C区温度过高");
    mapGZ->insert("11","D区温度过高");
    mapGZ->insert("12","E区温度过高");
    mapGZ->insert("13","F区温度过高");
    mapGZ->insert("14","A区温度异常");
    mapGZ->insert("15","B区温度异常");
    mapGZ->insert("16","C区温度异常");
    mapGZ->insert("17","D区温度异常");
    mapGZ->insert("18","E区温度异常");
    mapGZ->insert("19","F区温度异常");
    mapGZ->insert("1A","水泵故障");
    mapGZ->insert("1B","风扇故障");
    mapGZ->insert("1C","仓门打开");
    mapGZ->insert("1D","ad模块通信异常");
    mapGZ->insert("1E","升降电机位置异常");
    mapGZ->insert("1F","开关门电机位置异常");

    //自动连接在信号发射时被识别为队列连接/信号在主线程发射
    connect(this, &SerialportClient::SignalConnectToHost, this, [&](const QString & serialNamePort, QString baud) {
        QSerialPort::BaudRate baudRate;

        if(baud=="115200"){
            baudRate = QSerialPort::Baud115200;
        }
        else if(baud=="4800")
        {
            baudRate = QSerialPort::Baud4800;
        }
        else if(baud=="9600")
        {
            baudRate = QSerialPort::Baud9600;
        }
        else
        {
            return;
        }

        this->setDataBits(QSerialPort::Data8);
        this->setParity(QSerialPort::NoParity);
        this->setStopBits(QSerialPort::OneStop);
        this->setFlowControl(QSerialPort::NoFlowControl);
        this->setPortName(serialNamePort);
        this->setBaudRate(baudRate);
        if(this->open(QIODevice::ReadWrite))
        {
            m_bOnLine = true;
        }
        else
        {
            m_bOnLine = false;
        }
    }, Qt::AutoConnection);

    //收到了TCP服务的数据
    QObject::connect(this, &QIODevice::readyRead, this, [&]() {
        //        qDebug() << "收到TCP服务器数据" << QThread::currentThreadId() << "EquId:" << equId;
        logClient=loghelper::getInstance();
        QByteArray arr = this->readAll();
        QString str;
        for(int c :arr)
        {
            if(c>=0)
            {
                str += QString(" %1").arg(c, 2, 16, QChar('0')).toUpper();
            }
            else
            {
                str += QString(" %1").arg(c+256, 2, 16, QChar('0')).toUpper();
            }
        }
        str= str.simplified();
        logClient->WriteLog("CommLog","接收:\n"+str,equId);
        QStringList list=str.split(" ");

        if(list.length()>12){
            recvvalue = str;
            recfl.set(1);
            if(list[2]=="00" && list[3]=="38"){
                if(list[10]=="00" && list[11]=="00"){
                    experimentStatus=1;
                    emit successStart();
                }
                else if(list[10]=="00" &&list[11]=="01"){
                    experimentStatus=0;
                    emit successStart();
                }
            }


            if( list[3]=="3D" && list[7]=="07"){
                if(list.length()>150)//荧光数据
                {
                    if(tempString.isEmpty()){
                        tempString = str;
                    }else{
                        tempString.append(" "+str);
                    }
                    str=tempString;
                    tempString.clear();
                    QStringList list1=str.split(" ");
                    for(int i=12;i<list1.length()-4;i+=10){
                        if(i+4>list1.length()||i+5>list1.length()||i+6>list1.length()||i+7>list1.length()||
                                i+8>list1.length()||i+9>list1.length()){
                            break;
                        }else{
                            QSqlDatabase db = dbHelper::openConnection();
                            QSqlQuery query(db);

                            QString sql=QString("Insert into FluorescenceData values('%1','%2','','%3','%4','%5',"
                                                "'%6','%7','%8')").arg
                                    (
                                        common->GetGuid(),experimentGuid,
                                        common->SixteenToTen(list1[i]+" "+list1[i+1]),common->SixteenToTen(list1[11]),
                                    common->SixteenToTen(list1[i+2]+" "+ list1[i+3]),common->SixteenToTen(list1[i+4]+" "+ list1[i+5]),
                                    common->SixteenToTen(list1[i+6]+" "+ list1[i+7]),common->SixteenToTen(list1[i+8]+" "+ list1[i+9])
                                    );
                            query.exec(sql);
                        }
                    }
                    QSqlDatabase db = dbHelper::openConnection();
                    QSqlQuery query(db);

                    db.transaction();
                    QString sql=QString("update FluorescenceData set SampleId=(select id from sampleInfo s "
                                        "where ExperimentGuid='%2' and "
                                        "case "
                                        "when FluorescenceData.PositionNumber %1 = 0 "
                                        "then s.RowNum=7 and s.ColNum=FluorescenceData.PositionNumber/8-1 "
                                        "else "
                                        "s.RowNum = FluorescenceData.PositionNumber %1-1 and s.ColNum = FluorescenceData.PositionNumber/8 "
                                        "end) Where ExperimentGuid='%2'").arg("%8",experimentGuid);
                    query.exec(sql);
                    //                        qDebug() << "sql2 ====" << sql;

                    sql=QString("DELETE FROM FluorescenceData WHERE ExperimentGuid='%1' rowid NOT IN (SELECT MIN(rowid) FROM FluorescenceData GROUP BY positionNumber, CyclesNumber)").arg(experimentGuid);

                    //                        qDebug() << "sql3 ====" << sql;
                    query.exec(sql);
                    db.commit();

                }
            }

            if((list[0]=="62" && list[1]=="00" && list[2]=="00" && list[3]=="3A")||!tempString.isEmpty())
            {
                if(list.length()==30 )//温度数据
                {
                    step=common->SixteenToTen(list[10]);
                    cycle=common->SixteenToTen(list[11]);
                    QString originalTemp=common->SixteenToTen(list[12]+" "+list[13]);
                    double val= originalTemp.toDouble()/100;
                    temp=QString::number(val,'f',2);
                    tempOrder = list[25].toInt();

                    tempTwo=QString::number(common->SixteenToTen(list[14]+" "+list[15]).toDouble()/100,'f',2);
                    tempThree=QString::number(common->SixteenToTen(list[16]+" "+list[17]).toDouble()/100,'f',2);
                    tempFour=QString::number(common->SixteenToTen(list[18]+" "+list[19]).toDouble()/100,'f',2);
                    tempFive=QString::number(common->SixteenToTen(list[20]+" "+list[21]).toDouble()/100,'f',2);
                    tempSix=QString::number(common->SixteenToTen(list[22]+" "+list[23]).toDouble()/100,'f',2);
                }
                if(list.length()>400)//荧光数据
                {
                    if(list[list.length()-2]!="AA"&& list[list.length()-1]!="55"){
                        tempString.append(str);
                    }
                    else
                    {
                        if(list[list.length()-2]=="AA"&& list[list.length()-1]=="55" && tempString.isEmpty()){
                            tempString = str;
                        }else{
                            tempString.append(" "+str);
                        }
                        str=tempString;
                        tempString.clear();
                        QStringList list1=str.split(" ");
                        for(int i=12;i<list1.length()-4;i+=10){
                            if(i+4>list1.length()||i+5>list1.length()||i+6>list1.length()||i+7>list1.length()||
                                    i+8>list1.length()||i+9>list1.length()){
                                break;
                            }else{
                                QSqlDatabase db = dbHelper::openConnection();
                                QSqlQuery query(db);

                                QString sql=QString("Insert into FluorescenceData values('%1','%2','','%3','%4','%5',"
                                                    "'%6','%7','%8')").arg
                                        (
                                            common->GetGuid(),experimentGuid,
                                            common->SixteenToTen(list1[i]+" "+list1[i+1]),common->SixteenToTen(list1[11]),
                                        common->SixteenToTen(list1[i+2]+" "+ list1[i+3]),common->SixteenToTen(list1[i+4]+" "+ list1[i+5]),
                                        common->SixteenToTen(list1[i+6]+" "+ list1[i+7]),common->SixteenToTen(list1[i+8]+" "+ list1[i+9])
                                        );
                                //                                qDebug() << "sql1 ====" << sql;
                                query.exec(sql);
                            }
                        }
                        QSqlDatabase db = dbHelper::openConnection();
                        QSqlQuery query(db);

                        db.transaction();
                        QString sql=QString("update FluorescenceData set SampleId=(select id from sampleInfo s "
                                            "where ExperimentGuid='%2' and "
                                            "case "
                                            "when FluorescenceData.PositionNumber %1 = 0 "
                                            "then s.RowNum=7 and s.ColNum=FluorescenceData.PositionNumber/8-1 "
                                            "else "
                                            "s.RowNum = FluorescenceData.PositionNumber %1-1 and s.ColNum = FluorescenceData.PositionNumber/8 "
                                            "end) Where ExperimentGuid='%2'").arg("%8",experimentGuid);
                        query.exec(sql);
                        //                        qDebug() << "sql2 ====" << sql;

                        sql=QString("DELETE FROM FluorescenceData WHERE ExperimentGuid='%1' rowid NOT IN (SELECT MIN(rowid) FROM FluorescenceData GROUP BY positionNumber, CyclesNumber)").arg(experimentGuid);

                        //                        qDebug() << "sql3 ====" << sql;
                        query.exec(sql);
                        db.commit();

                        chartStatus="1";
                    }
                }
            }
        }

        // cnr 07发送 6.25
        QString Data=str.remove(QRegExp("\\s"));
        QString ty = Data.mid(4,4);
        QString wendubs = Data.mid(8,4);
        QString isright = Data.mid(12,4);
        QString isright2 = Data.mid(16,4);
        QString rw = Data.mid(50,2);
        if(ty=="003A"){
            allerror.clear();

            QString gzfl = Data.mid(Data.length()-10,2);
            if (wendubs=="0018"&&rw=="07"&&Data.length()==60) {
                if(rw=="07"){
                    order order1;
                    this->write(order1.toByteArray("6200","003A","000A","000100010007","1652","55AA"));
                }
            }else if(gzfl=="07"){
                int flnum=0;
                for(int i=24;i<=Data.length()-14;i+=2){
                    QString gzdz = Data.mid(i,2);
                    QString gzdzv=mapGZ->value(gzdz);
                    if((flnum+1)%4==0){
                        allerror += gzdzv+"\n";
                    }else{
                        allerror += gzdzv+";";
                    }
                }
                QMLSignal::I().emitExperimentError(equId);     // 发信号通知前端
            }
        }
    }, Qt::DirectConnection);

    //执行数据发送过程
    QObject::connect(this, &SerialportClient::SignalSendingData, this, [&](const QByteArray c_btaData){
        this->write(c_btaData);
    }, Qt::AutoConnection);
}

//跨线程转换
void SerialportClient::ClientConnectToHost(const QString & address, QString port)
{
    emit SignalConnectToHost(address, port);
}

//跨线程转换
void SerialportClient::ClientSendingData(const QByteArray & c_btaData)
{
    //    qDebug() << __FUNCTION__ << QThread::currentThreadId() << "EquId:" << equId;
    emit SignalSendingData(c_btaData);
}


void SerialportClient::serialclose(){
    if(this->isOpen())
    {
        this->close();
    }
}
//是否在线
bool SerialportClient::IsOnline()
{
    return m_bOnLine;
}
